﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml;
using System.Xml.Serialization;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Formatting = Newtonsoft.Json.Formatting;

namespace LSUtility
{
    public static class BaseTool
    {
        public static string Week
        {
            get
            {
                string[] weekdays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
                var week = weekdays[Convert.ToInt32(DateTime.Now.DayOfWeek)];
                return week;
            }
        }

        public static string ComputerName
        {
            get { return HttpContext.Current.Server.MachineName; }
        }

        public static string StringGetMD5(this string str)
        {
            var r = FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5");
            if (!String.IsNullOrEmpty(r)) r = r.ToLower();
            return r;
        }

        /// <summary>
        /// 是否是Post提交
        /// </summary>
        public static bool IsPost
        {
            get
            {
                var method = HttpContext.Current.Request.HttpMethod;
                return !String.IsNullOrEmpty(method) && method.Equals("POST");
            }
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <param name="context"> </param>
        /// <param name="paramsName"></param>
        /// <returns></returns>
        public static string RequestGetValue(this HttpContext context, string paramsName)
        {
            var formValue = context.Request.Form[paramsName].StringReturnDefault(String.Empty);
            var queryStringValue = context.Request.QueryString[paramsName].StringReturnDefault(String.Empty);
            var itemValue = context.Items[paramsName.ToLower()].Obj2Str();
            if (!String.IsNullOrEmpty(queryStringValue))
            {
                return queryStringValue;
            }
            if (!String.IsNullOrEmpty(formValue))
            {
                return formValue;
            }
            return !String.IsNullOrEmpty(itemValue) ? itemValue : String.Empty;
            //return String.IsNullOrEmpty(formValue)
            //           ? context.Request.QueryString[paramsName].StringReturnDefault(String.Empty)
            //           : formValue;
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <param name="context"> </param>
        /// <param name="paramsName"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static int RequestGetValue(this HttpContext context, string paramsName, int defaultValue)
        {
            int r;
            var formValue = context.Request.Form[paramsName].StringReturnDefault(String.Empty);
            var queryStringValue = context.Request.QueryString[paramsName].StringReturnDefault(String.Empty);
            var itemValue = context.Items[paramsName.ToLower()].Obj2Str();
            if (!String.IsNullOrEmpty(queryStringValue))
            {
                if (!int.TryParse(queryStringValue, out r))
                {
                    r = defaultValue;
                }
            }
            else if (!String.IsNullOrEmpty(formValue))
            {
                if (!int.TryParse(formValue, out r))
                {
                    r = defaultValue;
                }
            }
            else
            {
                if (!int.TryParse(itemValue, out r))
                {
                    r = defaultValue;
                }
            }
            return r;
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <param name="context"> </param>
        /// <param name="paramsName"></param>
        /// <returns></returns>
        public static List<T> RequestGetValue<T>(this HttpContext context, string paramsName)
        {
            string v;
            var r = new List<T>();
            var formValue = context.Request.Form[paramsName].StringReturnDefault(String.Empty);
            var queryStringValue = context.Request.QueryString[paramsName].StringReturnDefault(String.Empty);
            var itemValue = context.Items[paramsName.ToLower()].Obj2Str();
            if (!String.IsNullOrEmpty(queryStringValue))
            {
                v = queryStringValue;
            }
            else if (!String.IsNullOrEmpty(formValue))
            {
                v = formValue;
            }
            else
            {
                v = itemValue;
            }
            if (!String.IsNullOrEmpty(v))
            {
                try
                {
                    r.AddRange(v.Split(',').Select(s => (T)Convert.ChangeType(s, typeof(T))));
                }
                catch (Exception)
                {

                }
            }
            return r;
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="paramsName"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static bool RequestGetValue(this HttpContext context, string paramsName, bool defaultValue)
        {
            int r;
            bool b;
            var formValue = context.Request.Form[paramsName].StringReturnDefault(String.Empty);
            var queryStringValue = context.Request.QueryString[paramsName].StringReturnDefault(String.Empty);
            var itemValue = context.Items[paramsName].Obj2Str();
            if (!String.IsNullOrEmpty(queryStringValue))
            {
                if (int.TryParse(queryStringValue, out r))
                {
                    return r > 0;
                }
                if (!bool.TryParse(queryStringValue, out b))
                {
                    return b;
                }
            }
            else if (int.TryParse(formValue, out r))
            {
                if (int.TryParse(formValue, out r))
                {
                    return r > 0;
                }
                if (!bool.TryParse(formValue, out b))
                {
                    return b;
                }
            }
            else
            {
                if (int.TryParse(itemValue, out r))
                {
                    return r > 0;
                }
                if (!bool.TryParse(itemValue, out b))
                {
                    return b;
                }
            }
            return defaultValue;
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context"></param>
        /// <returns></returns>
        public static T RequestGetT<T>(this HttpContext context) where T : new()
        {
            return RequestGetT<T>(context, String.Empty);
        }

        /// <summary>
        /// 获取Form或Request中的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context"></param>
        /// <param name="group">OUP.Entity.SubmitTitle.Group中的值</param>
        /// <returns></returns>
        public static T RequestGetT<T>(this HttpContext context, string group) where T : new()
        {
            var t = new T();
            foreach (var propertyInfo in t.GetType().GetProperties())
            {
                foreach (var customAttribute in propertyInfo.GetCustomAttributes(false))
                {
                    var attr = customAttribute as SubmitTitle;
                    if (attr != null && (attr.Group == group || String.IsNullOrEmpty(group)))
                    {
                        var paramsName = attr.Title;
                        if (String.IsNullOrEmpty(paramsName)) paramsName = propertyInfo.Name;
                        if (propertyInfo.PropertyType.IsEnum)
                        {
                            try
                            {
                                propertyInfo.SetValue(t,
                                                  Enum.Parse(propertyInfo.PropertyType,
                                                             context.RequestGetValue(paramsName)), null);
                            }
                            catch
                            {

                            }
                        }
                        else
                        {
                            try
                            {
                                propertyInfo.SetValue(t,
                                              Convert.ChangeType(context.RequestGetValue(paramsName),
                                                                 propertyInfo.PropertyType), null);
                            }
                            catch
                            {

                            }

                        }

                    }
                }
            }
            return t;
        }

        /// <summary>
        /// 根据实体自动获取插入或更新语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string InsertStrGet<T>(this T t, out ICollection<MySqlParameter> paramList)
        {
            return InsertStrGet(t, String.Empty, out paramList);
        }

        /// <summary>
        /// 根据实体自动获取插入或更新语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public static string InsertStrGet<T>(this T t, string group, out ICollection<MySqlParameter> paramList)
        {
            paramList = new List<MySqlParameter>();
            #region get table
            var table = String.Empty;
            var isUpdate = false;
            var tb = typeof(T).GetCustomAttributes(false).Where(m => (m is Insert));
            if (tb.Any())
            {
                if (!String.IsNullOrEmpty(group)) tb = tb.Where(m => (m as Insert).Group == group);
                var first = (tb.FirstOrDefault() as Insert);
                if (first != null)
                {
                    table = first.Field;
                    isUpdate = first.IsUpdate;
                }
            }
            if (String.IsNullOrEmpty(table)) table = typeof(T).Name;
            #endregion
            #region get field

            string fields = String.Empty, values = String.Empty, updateFields = String.Empty;
            foreach (var propertyInfo in t.GetType().GetProperties())
            {
                foreach (var customAttribute in propertyInfo.GetCustomAttributes(false))
                {
                    if (!(customAttribute is Insert)) continue;
                    var cust = customAttribute as Insert;
                    if (!String.IsNullOrEmpty(@group) && cust.Group != @group) continue;
                    var field = cust.Field;
                    if (String.IsNullOrEmpty(field)) field = propertyInfo.Name;
                    var val = propertyInfo.GetValue(t, null);
                    if (propertyInfo.PropertyType.IsEnum) val = (int)val;
                    //if (propertyInfo.PropertyType == typeof(string) || propertyInfo.PropertyType == typeof(DateTime))
                    //{
                    //    fields += String.Format(",{0}", field);
                    //    values += String.Format(",'@{0}'", field);

                    //    //values += ",'" + val + "'";
                    //    updateFields += String.Format(",{0}='@{0}'", field);

                    //    paramList.Add(MakeParameter("@" + field, GetMySqlDbType(propertyInfo.PropertyType), val));
                    //}
                    //else
                    //{
                    //    //fields += "," + field;
                    //    //values += "," + val;
                    //    //updateFields += String.Format(",{0}={1}", field, val);

                    //    fields += String.Format(",{0}", field);
                    //    values += String.Format(",@{0}", field);
                    //    updateFields += String.Format(",{0}=@{0}", field);

                    //    paramList.Add(MakeParameter("@" + field, GetMySqlDbType(propertyInfo.PropertyType), val));
                    //}
                    fields += String.Format(",{0}", field);
                    values += String.Format(",@{0}", field);
                    updateFields += String.Format(",{0}=@{0}", field);
                    paramList.Add(MakeParameter("@" + field, GetMySqlDbType(propertyInfo.PropertyType), val));
                }
            }
            #endregion
            if (fields.IndexOf(',') == 0) fields = fields.Substring(1);
            if (values.IndexOf(',') == 0) values = values.Substring(1);
            if (updateFields.IndexOf(',') == 0) updateFields = updateFields.Substring(1);
            return isUpdate
                       ? String.Format("update {0} set {1}", table, updateFields)
                       : String.Format("insert into {0}({1}) values({2})", table, fields, values);
        }

        public static MySqlParameter MakeParameter(String paramName, MySqlDbType dbType, object paramValue)
        {
            return new MySqlParameter
            {
                ParameterName = paramName,
                MySqlDbType = dbType,
                Value = paramValue
            };
        }


        public static MySqlDbType GetMySqlDbType(this Type type)
        {
            if (type == typeof(int))
            {
                return MySqlDbType.Int32;
            }
            else if (type == typeof(string))
            {
                return MySqlDbType.String;
            }
            else if (type == typeof(float))
            {
                return MySqlDbType.Float;
            }
            else if (type == typeof(decimal))
            {
                return MySqlDbType.Decimal;
            }
            else if (type == typeof(bool))
            {
                return MySqlDbType.Int16;
            }
            else if (type == typeof(DateTime))
            {
                return MySqlDbType.DateTime;
            }
            else if (type == typeof(short))
            {
                return MySqlDbType.Int16;
            }
            return MySqlDbType.String;
        }

        /// <summary>
        /// 获取某实体类的属性和类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static List<CommonList<string, Type>> GetTypeAndName<T>(this T t)
        {
            return t.GetType().GetProperties().Select(propertyInfo => new CommonList<string, Type>
            {
                Tt1 = propertyInfo.Name,
                Tt2 = propertyInfo.PropertyType,
            }).ToList();
        }

        /// <summary>
        /// 未属性赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public static void PropertySetValue<T>(this T t, string propertyName, object value)
        {
            try
            {
                t.GetType().GetProperty(propertyName).SetValue(t, value, null);
            }
            catch
            {

            }

        }

        /// <summary>
        /// 把enum生成位操作的or语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="taskTypes"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public static string EnumListCreateBitToOr<T>(this List<T> taskTypes, string field)
        {
            if (taskTypes == null) return String.Empty;
            var rData = String.Empty;
            //var val =
            //    taskTypes.Where(taskType => Convert.ToInt32(taskType) > 0).Sum(taskType => Convert.ToInt32(taskType));
            foreach (var kv in taskTypes)
            {
                if (String.IsNullOrEmpty(rData))
                {
                    rData = String.Format(" {0} & {1}={0} ", Convert.ToInt32(kv), field);
                }
                else
                {
                    rData += String.Format(" or {0} & {1}={0} ", Convert.ToInt32(kv), field);
                }
            }
            if (!String.IsNullOrEmpty(rData)) rData = String.Format(" and ({0})", rData);
            return rData;
        }

        #region String扩展
        /// <summary>
        /// 字符串数组转化为int集合
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static List<int> StringArr2IntArr(this string[] sources)
        {
            var r = new List<int>();
            if (sources != null && sources.Length > 0)
            {
                foreach (var s in sources)
                {
                    int i;
                    if (int.TryParse(s, out i))
                    {
                        r.Add(i);
                    }
                }
            }
            return r;
        }

        public static List<String> String2ListStr(this string sources, char split)
        {
            return String.IsNullOrEmpty(sources) ? new List<string>() : sources.Split(split).ToList();
        }

        /// <summary>
        /// 字符串转化为int集合
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="splitStr"></param>
        /// <returns></returns>
        public static List<int> String2IntArr(this string sources, char splitStr)
        {
            return !String.IsNullOrEmpty(sources) ? StringArr2IntArr(sources.Split(splitStr)) : new List<int>();
        }

        /// <summary>获取字符串，只保留数字，字母，中文
        /// 获取字符串，只保留数字，字母，中文
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static string StringReplaceCodes(this string sources)       //检查字符串过滤方法
        {
            if (String.IsNullOrEmpty(sources)) return String.Empty;
            char[] buf = sources.ToCharArray();
            string tmp = string.Empty;
            for (int k = 0; k < buf.Length; k++)
            {
                if ((Convert.ToInt32(buf[k]) >= 48 && Convert.ToInt32(buf[k]) < 58) ||        //数字
                 (Convert.ToInt32(buf[k]) >= 65 && Convert.ToInt32(buf[k]) < 91) ||            //大写字母
                (Convert.ToInt32(buf[k]) >= 97 && Convert.ToInt32(buf[k]) < 123) ||           //小写字母
                    (Convert.ToInt32(buf[k]) == 46) ||                                            //.
                    (Convert.ToInt32(buf[k]) == 44) ||                                            //,
                    (Convert.ToInt32(buf[k]) == 32) ||                                            //空格
                    (Convert.ToInt32(buf[k]) == 95) ||                                            //下划线
                    (Convert.ToInt32(buf[k]) == 45) ||                                            //中划线
                    //(Convert.ToInt32(buf[k]) == 64) ||                                            //@
                (Convert.ToInt32(buf[k]) > 127))                                            //中文
                //(Convert.ToInt32(buf[k]) == 8))                                               //退格
                {
                    tmp += buf[k].ToString(CultureInfo.InvariantCulture);

                }
            }
            return tmp;
        }

        /// <summary>去固定长度的字符串
        /// 去固定长度的字符串
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string StringGetLength(this string sources, int length)
        {
            if (String.IsNullOrEmpty(sources)) return String.Empty;

            var bytesCount = 0;
            var myEncoding = Encoding.GetEncoding("GB2312");

            var cutStrBytes1 = new byte[length];
            var sourceStrBytes = myEncoding.GetBytes(sources);
            bytesCount = sourceStrBytes.Length;
            if (bytesCount > length)
            {
                Array.Copy(sourceStrBytes, 0, cutStrBytes1, 0, length);
                var cutedStr = myEncoding.GetString(cutStrBytes1);
                cutedStr = cutedStr.Substring(0, cutedStr.Length - 1) + "...";
                return cutedStr;
            }
            return sources;
        }

        /// <summary>获取指定长度的字符串
        /// 获取指定长度的字符串
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string StringGetSubstring(this string sources, int length)
        {
            if (length < 0) return sources;
            if (String.IsNullOrEmpty(sources)) return String.Empty;
            return sources.Length > length ? sources.Substring(0, length) : sources;
        }

        #region 加解密
        /// <summary>
        /// 密钥
        /// </summary>
        private const string sKey = "qJzGEh6hESZDVJeCnFPGuxzaiB7NLQM3";
        /// <summary>
        /// 矢量，矢量可以为空
        /// </summary>
        private const string sIV = "qcDY6X+aPLw=";
        /// <summary>
        /// 构造一个对称算法
        /// </summary>
        private static SymmetricAlgorithm mCSP = new TripleDESCryptoServiceProvider();

        #region public string EncryptString(string Value)
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="value">输入的字符串</param>
        /// <param name="isUrlArge">是否作为URL的差数而加密</param>
        /// <returns>加密后的字符串</returns>
        public static string EncryptString(this string value, bool isUrlArge)
        {
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;
            mCSP.Key = Convert.FromBase64String(sKey);
            mCSP.IV = Convert.FromBase64String(sIV);
            //指定加密的运算模式
            mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
            //获取或设置加密算法的填充模式
            mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV);
            byt = Encoding.UTF8.GetBytes(value);
            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return isUrlArge
                       ? Convert.ToBase64String(ms.ToArray()).Replace("+", "%2B")
                       : Convert.ToBase64String(ms.ToArray());
        }

        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="value">输入的字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string EncryptString(this string value)
        {
            return EncryptString(value, false);
        }

        #endregion

        #region public string DecryptString(string Value)
        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <returns>解密后的字符串</returns>
        public static string DecryptString(this string value, bool isUrl)
        {
            if (!String.IsNullOrEmpty(value))
            {
                if (isUrl) value = value.Replace("%2B", "+");
                ICryptoTransform ct;
                MemoryStream ms;
                CryptoStream cs;
                byte[] byt;
                mCSP.Key = Convert.FromBase64String(sKey);
                mCSP.IV = Convert.FromBase64String(sIV);
                mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
                mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
                ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);
                byt = Convert.FromBase64String(value);
                ms = new MemoryStream();
                cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
                cs.Write(byt, 0, byt.Length);
                cs.FlushFinalBlock();
                cs.Close();
                return Encoding.UTF8.GetString(ms.ToArray());
            }
            return value;
        }
        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <returns>解密后的字符串</returns>
        public static string DecryptString(this string value)
        {
            return DecryptString(value, false);
        }

        #endregion
        #endregion

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="sources">目录路径</param>
        public static string StringToCreatePath(this string sources)
        {
            try
            {
                if (!String.IsNullOrEmpty(sources))
                {
                    if (!Directory.Exists(sources)) Directory.CreateDirectory(sources);

                    return sources;
                }
            }
            catch
            {
            }
            return String.Empty;
        }

        /// <summary>
        /// 当sources为空时返回默认值
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="defaultStr">默认值</param>
        /// <returns></returns>
        public static string StringReturnDefault(this string sources, string defaultStr)
        {
            return String.IsNullOrEmpty(sources) ? defaultStr : sources;
        }

        /// <summary>
        /// 判断字符串是否为Int
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static bool StringCheckIsInt(this string sources)
        {
            if (!String.IsNullOrEmpty(sources))
            {
                int r;
                if (int.TryParse(sources, out r))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// String转Int
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static int String2Int(this string sources, int? defaultValue)
        {
            int d = defaultValue.HasValue ? defaultValue.Value : 0;
            if (String.IsNullOrEmpty(sources)) return d;
            int r;
            if (int.TryParse(sources, out r)) return r;
            return d;
        }

        public static bool String2Bool(this string sources, bool? defaultValue)
        {
            var d = defaultValue.HasValue && defaultValue.Value;
            if (String.IsNullOrEmpty(sources)) return d;
            bool r;
            return bool.TryParse(sources, out r) ? r : d;
        }

        public static DateTime? String2DateTime(this string sources)
        {
            if (String.IsNullOrEmpty(sources)) return null;
            DateTime dt;
            if (DateTime.TryParse(sources, out dt))
            {
                return dt;
            }
            return null;
        }

        public static short String2Short(this string sources, short? defaultValue)
        {
            var d = defaultValue.HasValue ? defaultValue.Value : (short)0;
            if (String.IsNullOrEmpty(sources)) return d;
            short r;
            return short.TryParse(sources, out r) ? r : d;
        }

        public static double String2Double(this string sources, double? defaultValue)
        {
            double d = defaultValue.HasValue ? defaultValue.Value : 0;
            if (String.IsNullOrEmpty(sources)) return d;
            double r;
            if (double.TryParse(sources, out r)) return r;
            return d;
        }

        /// <summary>
        /// String转Float
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static float String2Float(this string sources, float? defaultValue)
        {
            float d = defaultValue.HasValue ? defaultValue.Value : 0;
            if (String.IsNullOrEmpty(sources)) return d;
            float r;
            if (float.TryParse(sources, out r)) return r;
            return d;
        }

        /// <summary>
        /// 是否和另外一个字符串一样
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="otherString"></param>
        /// <returns></returns>
        public static bool StringIsOtherString(this string sources, string otherString)
        {
            if (String.IsNullOrEmpty(sources) || String.IsNullOrEmpty(otherString)) return false;
            return sources.ToLower() == otherString.ToLower();
        }

        /// <summary>
        /// 判断字符串是否为Double
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static bool StringCheckIsDouble(this string sources)
        {
            if (!String.IsNullOrEmpty(sources))
            {
                double r;
                if (double.TryParse(sources, out r))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 将JSON字符串反序列化为NET对象
        /// </summary>
        public static T JsonToObj<T>(this string json)
        {
            //DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            //T obj;

            //using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            //{
            //    obj = (T)ser.ReadObject(ms);
            //}
            //return obj;
            return JsonConvert.DeserializeObject<T>(json);
        }

        public static List<T> ListToAddOrModify<T>(this List<T> sources, T model, Func<T, bool> where) where T : class
        {
            if (model != null)
            {
                if (sources == null)
                {
                    return new List<T> { model };
                }
                else
                {
                    if (sources.Any(where))
                    {
                        for (var i = 0; i < sources.Count; i++)
                        {
                            if (new List<T> { sources[i] }.Any(where))
                            {
                                sources[i] = model;
                            }
                        }
                    }
                    else
                    {
                        sources.Add(model);
                    }
                }
            }
            return sources;
        }

        #endregion

        #region Object扩展

        public static string Obj2Str(this object sources, string format = null)
        {
            if (sources == null) return String.Empty;
            if (!String.IsNullOrEmpty(format))
            {
                DateTime dt;
                if (DateTime.TryParse(sources.ToString(), out dt))
                {
                    return dt.ToString(format);
                }
            }
            return sources.ToString();
        }

        public static bool Obj2Bool(this object sources, bool defaultValue = false)
        {
            if (sources == null) return defaultValue;
            bool bl;
            return Boolean.TryParse(sources.ToString(), out bl) ? bl : defaultValue;
        }

        public static int Obj2Int(this object sources, int defaultValue)
        {
            if (sources == null) return defaultValue;
            int r;
            return int.TryParse(sources.ToString(), out r) ? r : defaultValue;
        }

        public static int Obj2Int(this object sources)
        {
            return Obj2Int(sources, 0);
        }

        public static DateTime Obj2DateTime(this object sources)
        {
            return Obj2DateTime(sources, DateTime.MinValue);
        }

        public static DateTime Obj2DateTime(this object sources, DateTime defaultValue)
        {
            DateTime tm;
            if (DateTime.TryParse(sources.Obj2Str(), out tm))
            {
                defaultValue = tm;
            }
            return defaultValue;
        }

        public static short Obj2Short(this object sources, short defaultValue)
        {
            if (sources == null) return defaultValue;
            short r;
            return short.TryParse(sources.ToString(), out r) ? r : defaultValue;
        }

        public static string StrReplace(this string sources, string oldStr, string newStr)
        {
            return String.IsNullOrEmpty(sources) ? sources : sources.Replace(oldStr, newStr);
        }

        public static string List2Str<T, TKey>(this IEnumerable<T> sources, Expression<Func<T, TKey>> key)
        {
            return sources == null ? String.Empty : List2Str(sources, key, String.Empty);
        }

        public static string List2Str<T, TKey>(this IEnumerable<T> sources, Expression<Func<T, TKey>> key, string seed)
        {
            //var name = key.LamdaGetName();
            //var r = String.IsNullOrEmpty(name)
            //            ? sources.Aggregate(seed, (current, v) => current + ("," + v.Obj2Str()))
            //            : sources.Aggregate(seed, (current, v) => current + ("," + v.ObjGetValue(name).Obj2Str()));

            //if (String.IsNullOrEmpty(seed) && !String.IsNullOrEmpty(r) && r.IndexOf(",") == 0)
            //{
            //    r = r.Substring(1);
            //}
            //return r;
            return sources == null ? seed : List2Str(sources, key, seed, ",");
        }

        public static string List2Str<T, TKey>(this IEnumerable<T> sources, Expression<Func<T, TKey>> key, string seed, string splitStr)
        {
            if (sources == null) return String.Empty;
            if (String.IsNullOrEmpty(splitStr)) splitStr = ",";
            var name = key.LamdaGetName();
            var r = String.IsNullOrEmpty(name)
                        ? sources.Aggregate(seed, (current, v) => current + (splitStr + v.Obj2Str()))
                        : sources.Aggregate(seed, (current, v) => current + (splitStr + v.ObjGetValue(name).Obj2Str()));

            if (String.IsNullOrEmpty(seed) && !String.IsNullOrEmpty(r) && r.IndexOf(splitStr) == 0)
            {
                r = r.Substring(splitStr.Length);
            }
            return r;
        }

        public static List<int> ListEnum2ListInt<T>(this List<T> sources)
        {
            return sources.Select(source => Convert.ToInt32(source)).ToList();
        }

        /// <summary>
        /// 获取枚举变量值的 Description 属性
        /// </summary>
        /// <param name="obj">枚举变量</param>
        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
        public static string ObjGetDescription(this object obj)
        {
            return ObjGetDescription(obj, false);
        }

        /// <summary>
        /// 获取枚举变量值的 Description 属性 
        /// </summary>
        /// <param name="obj">枚举变量</param>
        /// <param name="isTop">是否改变为返回该类、枚举类型的头 Description 属性，而不是当前的属性或枚举变量值的 Description 属性</param>
        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
        public static string ObjGetDescription(this object obj, bool isTop)
        {
            if (obj == null) return string.Empty;
            try
            {
                var enumType = obj.GetType();
                DescriptionAttribute dna;
                if (isTop)
                {
                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(enumType, typeof(DescriptionAttribute));
                }
                else
                {
                    var fi = enumType.GetField(Enum.GetName(enumType, obj));
                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(
                       fi, typeof(DescriptionAttribute));
                }
                if (dna != null && string.IsNullOrEmpty(dna.Description) == false)
                    return dna.Description;
            }
            catch
            {
            }
            return obj.ToString();
        }

        /// <summary>
        /// 获取枚举的自定义属性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="TR"></typeparam>
        /// <param name="enumItem"></param>
        /// <param name="field">要获取值的字段名称</param>
        /// <returns></returns>
        private static T1 EnumGetCustomAttribute<T, T1, TR>(T enumItem, string field) where TR : class
        {
            var rType = default(T1);
            if (enumItem == null) return rType;

            var t = typeof(T);
            var info = t.GetFields();
            for (int i = 0; i < info.Length; i++)
            {
                if (info[i].Name == enumItem.ToString())
                {
                    var att = info[i].GetCustomAttributes(false);
                    foreach (Attribute a in att)
                    {
                        if (a is TR)
                        {
                            var bbb = a as TR;
                            var r = bbb.GetType().GetProperty(field).GetValue(bbb, null);
                            return (T1)Convert.ChangeType(r, typeof(T1));
                        }
                    }
                    break;
                }
            }
            return rType;
        }

        /// <summary>
        /// 获取枚举的自定义属性的值
        /// </summary>
        /// <typeparam name="T">枚举名称</typeparam>
        /// <typeparam name="T1">返回类型</typeparam>
        /// <typeparam name="TCustom">自定义属性名称</typeparam>
        /// <param name="enumItem"></param>
        /// <param name="field">要获取值的字段名称</param>
        /// <returns></returns>
        public static T1 EnumGetCustomAttribute<T, T1, TCustom>(this T enumItem, Expression<Func<TCustom, T1>> field) where TCustom : class
        {
            return EnumGetCustomAttribute<T, T1, TCustom>(enumItem, field.LamdaGetName());
        }

        /// <summary>
        /// 从Lamda中获取字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string LamdaGetName<T, TKey>(this Expression<Func<T, TKey>> key)
        {
            var member = key.Body as MemberExpression;
            return member == null ? String.Empty : member.Member.Name;
        }

        public static List<String> ObjGetProperty<T>(this T sources) where T : class
        {
            var result = new List<String>();
            sources.GetType().GetProperties().ToList().ForEach(m => result.Add(m.Name));
            return result;
        }

        public static string GetStringFromTxt(string xnPath)
        {
            var path = HttpContext.Current.Server.MapPath(xnPath);
            return File.Exists(path) ? File.ReadAllText(path) : String.Empty;
        }

        /// <summary>
        /// 替换模板中的变量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <param name="tempHtml"></param>
        /// <returns></returns>
        public static string TempFormat<T>(this T sources, string tempHtml)
        {
            if (!String.IsNullOrEmpty(tempHtml))
            {
                var properties = sources.GetType().GetProperties();
                foreach (var property in properties)
                {
                    var name = property.Name;
                    var val = property.GetValue(sources, null).Obj2Str();
                    if (!String.IsNullOrEmpty(name))
                    {
                        tempHtml = tempHtml.Replace("{" + name + "}", val);
                        tempHtml = tempHtml.Replace("{" + name.ToLower() + "}", val);
                    }
                }
            }
            return tempHtml;
        }

        /// <summary>
        /// 获取循环各部分
        /// </summary>
        /// <param name="temp"></param>
        /// <returns></returns>
        public static string[] GetLoopArray(string temp)
        {
            var rStr = new string[3];
            const string begin = "${LoopBegin}", end = "${LoopEnd}";

            if (temp.IndexOf(begin, System.StringComparison.Ordinal) == -1 ||
                temp.IndexOf(end, System.StringComparison.Ordinal) == -1)
            {
                rStr[0] = String.Empty;
                rStr[1] = temp;
                rStr[2] = String.Empty;
            }
            else
            {
                rStr[0] = temp.IndexOf(begin, System.StringComparison.Ordinal) > 0
                              ? temp.Substring(0, temp.IndexOf(begin, System.StringComparison.Ordinal))
                              : String.Empty;
                temp = temp.Replace(rStr[0] + begin, "");
                rStr[1] = temp.IndexOf(end, System.StringComparison.Ordinal) > 0
                              ? temp.Substring(0, temp.IndexOf(end, System.StringComparison.Ordinal))
                              : String.Empty;
                rStr[2] = temp.Replace(rStr[1] + end, "");
            }
            return rStr;
        }

        /// <summary>
        /// 从元数据获取值
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object ObjGetValue(this object sources, string name)
        {
            var property = sources.GetType().GetProperty(name);
            if (property == null) return null;

            if (property.PropertyType.IsEnum)
            {
                return (int)property.GetValue(sources, null);
            }

            return property.GetValue(sources, null);
        }

        /// <summary>
        /// 获取List数量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static int ListGetCount<T>(this IEnumerable<T> sources)
        {
            return sources != null ? sources.Count() : 0;
        }

        /// <summary>
        /// 向字典中添加数据，无需判断Key
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TVale"></typeparam>
        /// <param name="sources"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void DictionaryAdd<TKey, TVale>(this IDictionary<TKey, TVale> sources, TKey key, TVale value)
        {
            if (sources == null) return;

            if (sources.Any(m => m.Key.Equals(key))) return;

            sources.Add(key, value);
        }

        /// <summary>
        /// 插入list中不存在的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <param name="val"></param>
        public static void ListInsertNotTheSame<T>(this List<T> sources, T val) where T : class
        {
            if (sources != null && val != null && !sources.Any(m => m.Equals(val))) sources.Add(val);
        }

        /// <summary>
        /// 获取json字符串；主要用户生成String和Int等系统自带类型的Json
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static string LamdaToJson<T>(this List<Expression<Func<T>>> sources)
        {
            var list = (from expression in sources
                        select expression.Body as MemberExpression
                            into member
                            where member != null && !String.IsNullOrEmpty(member.Member.Name)
                            let val = ((FieldInfo)member.Member).GetValue(((ConstantExpression)member.Expression).Value)
                            select "\"" + member.Member.Name + "\":" + val).ToList();
            return "{" + list.List2Str(m => m) + "}";
        }

        /// <summary>
        /// 将NET对象序列化为JSON
        /// </summary>
        public static string ObjToJson(this object obj, string dateTimeFormat = null)
        {
            //DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());

            //using (MemoryStream ms = new MemoryStream())
            //{
            //    serializer.WriteObject(ms, obj);
            //    StringBuilder sb = new StringBuilder();
            //    sb.Append(Encoding.UTF8.GetString(ms.ToArray()));
            //    return sb.ToString();
            //}

            return JsonConvert.SerializeObject(obj, Formatting.None,
                                               dateTimeFormat == null
                                                   ? new IsoDateTimeConverter()
                                                   : new IsoDateTimeConverter
                                                         {
                                                             DateTimeFormat = dateTimeFormat
                                                         });
        }

        /// <summary>
        /// Enum转化List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static IDictionary<string, int> EnumToList<T>()
        {
            var rData = new Dictionary<string, int>();
            var temp = new List<CommonList<string, int, int>>();
            Enum.GetValues(typeof(T)).Cast<T>().ToList().ForEach(
                m =>
                {
                    var isHide = m.EnumGetCustomAttribute<T, bool, EnumOrder>(c => c.IsHide);
                    if (!isHide)
                    {
                        temp.Add(new CommonList<string, int, int>
                        {
                            Tt1 = m.ObjGetDescription(),
                            Tt2 = Convert.ToInt32(m),
                            //Tt3 = m.EnumGetCustomAttribute<T, int, EnumOrder>("Order"),
                            Tt3 = m.EnumGetCustomAttribute<T, int, EnumOrder>(c => c.Order),
                        });
                    }
                });
            rData = temp.OrderBy(m => m.Tt3).ToDictionary(m => m.Tt1, m => m.Tt2);
            return rData;
        }

        /// <summary>
        /// 获取select的option()
        /// </summary>
        /// <param name="sources"></param>
        /// <param name="selectValue"></param>
        /// <returns></returns>
        public static string ListToOption(this IDictionary<string, int> sources, string selectValue)
        {
            var sb = new StringBuilder();
            foreach (var source in sources)
            {
                sb.AppendFormat("<option value=\"{0}\"{2}>{1}</option>", source.Value, source.Key,
                                (source.Key.Equals(selectValue) ? " selected=\"selected\"" : String.Empty));
            }
            return sb.ToString();
        }

        public static String ListToOption<T, T1, T2>(this IEnumerable<T> sources, Expression<Func<T, T1>> value, Expression<Func<T, T2>> text, CommonList<T1, T2> defaultSelect = null, string selectValue = null) where T : class
        {
            var result = String.Empty;
            if (defaultSelect != null)
            {
                result += String.Format("<option value=\"{0}\">{1}</option>", defaultSelect.Tt1, defaultSelect.Tt2);
            }
            return sources.Aggregate(result,
                                     (current, model) =>
                                     current +
                                     String.Format("<option value=\"{0}\"{2}>{1}</option>",
                                                   model.GetValueFromEntity(value), model.GetValueFromEntity(text),
                                                   !String.IsNullOrEmpty(selectValue) &&
                                                   model.ObjGetValue(value.LamdaGetName())
                                                        .Obj2Str()
                                                        .ToLower()
                                                        .Equals(selectValue.ToLower())
                                                       ? " selected=\"selected\""
                                                       : String.Empty));
        }

        /// <summary>
        /// 把list中的某项置顶
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <param name="t"></param>
        public static void ListForOneTop<T>(this List<T> sources, T t)
        {
            if (t == null) return;
            sources.Remove(t);
            sources.Insert(0, t);
        }

        /// <summary>
        /// 把字符串集合按字符串的长度来排序
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static List<string> ListStrOrderByLength(this IList<string> sources)
        {
            return
                sources.ToDictionary(str => str, str => str.Length).OrderByDescending(m => m.Value).Select(m => m.Key).
                    ToList();
        }

        /// <summary>
        /// 获取实体中某个属性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1"></typeparam>
        /// <param name="t"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static T1 GetValueFromEntity<T, T1>(this T t, Expression<Func<T, T1>> expression) where T : class
        {
            if (t == null) return default(T1);
            return (T1)t.ObjGetValue(expression.LamdaGetName());
        }

        #endregion

        #region 拼音
        #region 拼音编码
        private static readonly int[] PyValue = new[]
    {
    -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,
    -20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763,
    -19756,-19751,-19746,-19741,-19739,-19728,-19725,-19715,-19540,-19531,-19525,-19515,
    -19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249,
    -19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006,
    -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735,
    -18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501,-18490,-18478,-18463,-18448,
    -18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183, -18181,-18012,
    -17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,
    -17733,-17730,-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482,
    -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942,-16915,-16733,
    -16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,-16452,-16448,
    -16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216,
    -16212,-16205,-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,
    -15933,-15920,-15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659,
    -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,-15408,-15394,
    -15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150,
    -15149,-15144,-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109,
    -14941,-14937,-14933,-14930,-14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902,
    -14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654,
    -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345,
    -14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112,
    -14109,-14099,-14097,-14094,-14092,-14090,-14087,-14083,-13917,-13914,-13910,-13907,
    -13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601,
    -13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343,
    -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076,
    -13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858,-12852,-12849,-12838,-12831,
    -12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,-12320,-12300,
    -12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,
    -11781,-11604,-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067,
    -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014,-10838,-10832,
    -10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,-10329,-10328,
    -10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254
    };
        private static readonly string[] PyName = new[]
    {
    "A","Ai","An","Ang","Ao","Ba","Bai","Ban","Bang","Bao","Bei","Ben",
    "Beng","Bi","Bian","Biao","Bie","Bin","Bing","Bo","Bu","Ba","Cai","Can",
    "Cang","Cao","Ce","Ceng","Cha","Chai","Chan","Chang","Chao","Che","Chen","Cheng",
    "Chi","Chong","Chou","Chu","Chuai","Chuan","Chuang","Chui","Chun","Chuo","Ci","Cong",
    "Cou","Cu","Cuan","Cui","Cun","Cuo","Da","Dai","Dan","Dang","Dao","De",
    "Deng","Di","Dian","Diao","Die","Ding","Diu","Dong","Dou","Du","Duan","Dui",
    "Dun","Duo","E","En","Er","Fa","Fan","Fang","Fei","Fen","Feng","Fo",
    "Fou","Fu","Ga","Gai","Gan","Gang","Gao","Ge","Gei","Gen","Geng","Gong",
    "Gou","Gu","Gua","Guai","Guan","Guang","Gui","Gun","Guo","Ha","Hai","Han",
    "Hang","Hao","He","Hei","Hen","Heng","Hong","Hou","Hu","Hua","Huai","Huan",
    "Huang","Hui","Hun","Huo","Ji","Jia","Jian","Jiang","Jiao","Jie","Jin","Jing",
    "Jiong","Jiu","Ju","Juan","Jue","Jun","Ka","Kai","Kan","Kang","Kao","Ke",
    "Ken","Keng","Kong","Kou","Ku","Kua","Kuai","Kuan","Kuang","Kui","Kun","Kuo",
    "La","Lai","Lan","Lang","Lao","Le","Lei","Leng","Li","Lia","Lian","Liang",
    "Liao","Lie","Lin","Ling","Liu","Long","Lou","Lu","Lv","Luan","Lue","Lun",
    "Luo","Ma","Mai","Man","Mang","Mao","Me","Mei","Men","Meng","Mi","Mian",
    "Miao","Mie","Min","Ming","Miu","Mo","Mou","Mu","Na","Nai","Nan","Nang",
    "Nao","Ne","Nei","Nen","Neng","Ni","Nian","Niang","Niao","Nie","Nin","Ning",
    "Niu","Nong","Nu","Nv","Nuan","Nue","Nuo","O","Ou","Pa","Pai","Pan",
    "Pang","Pao","Pei","Pen","Peng","Pi","Pian","Piao","Pie","Pin","Ping","Po",
    "Pu","Qi","Qia","Qian","Qiang","Qiao","Qie","Qin","Qing","Qiong","Qiu","Qu",
    "Quan","Que","Qun","Ran","Rang","Rao","Re","Ren","Reng","Ri","Rong","Rou",
    "Ru","Ruan","Rui","Run","Ruo","Sa","Sai","San","Sang","Sao","Se","Sen",
    "Seng","Sha","Shai","Shan","Shang","Shao","She","Shen","Sheng","Shi","Shou","Shu",
    "Shua","Shuai","Shuan","Shuang","Shui","Shun","Shuo","Si","Song","Sou","Su","Suan",
    "Sui","Sun","Suo","Ta","Tai","Tan","Tang","Tao","Te","Teng","Ti","Tian",
    "Tiao","Tie","Ting","Tong","Tou","Tu","Tuan","Tui","Tun","Tuo","Wa","Wai",
    "Wan","Wang","Wei","Wen","Weng","Wo","Wu","Xi","Xia","Xian","Xiang","Xiao",
    "Xie","Xin","Xing","Xiong","Xiu","Xu","Xuan","Xue","Xun","Ya","Yan","Yang",
    "Yao","Ye","Yi","Yin","Ying","Yo","Yong","You","Yu","Yuan","Yue","Yun",
    "Za", "Zai","Zan","Zang","Zao","Ze","Zei","Zen","Zeng","Zha","Zhai","Zhan",
    "Zhang","Zhao","Zhe","Zhen","Zheng","Zhi","Zhong","Zhou","Zhu","Zhua","Zhuai","Zhuan",
    "Zhuang","Zhui","Zhun","Zhuo","Zi","Zong","Zou","Zu","Zuan","Zui","Zun","Zuo"
    };
        #endregion 拼音编码
        /// <summary>从字符串中获取汉字拼音首字母，不是汉字则原样输出
        /// 从字符串中获取汉字拼音首字母，不是汉字则原样输出
        /// </summary>
        /// <param name="hz"></param>
        /// <returns></returns>
        public static string GetFirstPYLetter(this string hz)
        {
            const string lsSecondEng = "CJWGNSPGCGNESYPBTYYZDXYKYGTDJNNJQMBSGZSCYJSYYQPGKBZGYCYWJKGKLJSWKPJQHYTWDDZLSGMRYPYWWCCKZNKYDGTTNGJEYKKZYTCJNMCYLQLYPYQFQRPZSLWBTGKJFYXJWZLTBNCXJJJJZXDTTSQZYCDXXHGCKBPHFFSSWYBGMXLPBYLLLHLXSPZMYJHSOJNGHDZQYKLGJHSGQZHXQGKEZZWYSCSCJXYEYXADZPMDSSMZJZQJYZCDJZWQJBDZBXGZNZCPWHKXHQKMWFBPBYDTJZZKQHYLYGXFPTYJYYZPSZLFCHMQSHGMXXSXJJSDCSBBQBEFSJYHWWGZKPYLQBGLDLCCTNMAYDDKSSNGYCSGXLYZAYBNPTSDKDYLHGYMYLCXPYCJNDQJWXQXFYYFJLEJBZRXCCQWQQSBNKYMGPLBMJRQCFLNYMYQMSQTRBCJTHZTQFRXQ" +
                                         "HXMJJCJLXQGJMSHZKBSWYEMYLTXFSYDSGLYCJQXSJNQBSCTYHBFTDCYZDJWYGHQFRXWCKQKXEBPTLPXJZSRMEBWHJLBJSLYYSMDXLCLQKXLHXJRZJMFQHXHWYWSBHTRXXGLHQHFNMNYKLDYXZPWLGGTMTCFPAJJZYLJTYANJGBJPLQGDZYQYAXBKYSECJSZNSLYZHZXLZCGHPXZHZNYTDSBCJKDLZAYFMYDLEBBGQYZKXGLDNDNYSKJSHDLYXBCGHXYPKDJMMZNGMMCLGWZSZXZJFZNMLZZTHCSYDBDLLSCDDNLKJYKJSYCJLKOHQASDKNHCSGANHDAASHTCPLCPQYBSDMPJLPCJOQLCDHJJYSPRCHNWJNLHLYYQYYWZPTCZGWWMZFFJQQQQYXACLBHKDJXDGMMYDJXZLLSYGXGKJRYWZWYCLZMSSJZLDBYDCFCXYHLXCHYZJQSFQAGMNYXPFRKSSB" +
                                         "JLYXYSYGLNSCMHCWWMNZJJLXXHCHSYDSTTXRYCYXBYHCSMXJSZNPWGPXXTAYBGAJCXLYSDCCWZOCWKCCSBNHCPDYZNFCYYTYCKXKYBSQKKYTQQXFCWCHCYKELZQBSQYJQCCLMTHSYWHMKTLKJLYCXWHEQQHTQHZPQSQSCFYMMDMGBWHWLGSSLYSDLMLXPTHMJHWLJZYHZJXHTXJLHXRSWLWZJCBXMHZQXSDZPMGFCSGLSXYMJSHXPJXWMYQKSMYPLRTHBXFTPMHYXLCHLHLZYLXGSSSSTCLSLDCLRPBHZHXYYFHBBGDMYCNQQWLQHJJZYWJZYEJJDHPBLQXTQKWHLCHQXAGTLXLJXMSLXHTZKZJECXJCJNMFBYCSFYWYBJZGNYSDZSQYRSLJPCLPWXSDWEJBJCBCNAYTWGMPAPCLYQPCLZXSBNMSGGFNZJJBZSFZYNDXHPLQKZCZWALSBCCJXJYZGWKYP" +
                                         "SGXFZFCDKHJGXDLQFSGDSLQWZKXTMHSBGZMJZRGLYJBPMLMSXLZJQQHZYJCZYDJWBMJKLDDPMJEGXYHYLXHLQYQHKYCWCJMYYXNATJHYCCXZPCQLBZWWYTWBQCMLPMYRJCCCXFPZNZZLJPLXXYZTZLGDLDCKLYRZZGQTGJHHHJLJAXFGFJZSLCFDQZLCLGJDJCSNCLLJPJQDCCLCJXMYZFTSXGCGSBRZXJQQCTZHGYQTJQQLZXJYLYLBCYAMCSTYLPDJBYREGKLZYZHLYSZQLZNWCZCLLWJQJJJKDGJZOLBBZPPGLGHTGZXYGHZMYCNQSYCYHBHGXKAMTXYXNBSKYZZGJZLQJDFCJXDYGJQJJPMGWGJJJPKQSBGBMMCJSSCLPQPDXCDYYKYFCJDDYYGYWRHJRTGZNYQLDKLJSZZGZQZJGDYKSHPZMTLCPWNJAFYZDJCNMWESCYGLBTZCGMSSLLYXQSXSBSJS" +
                                         "BBSGGHFJLWPMZJNLYYWDQSHZXTYYWHMCYHYWDBXBTLMSYYYFSXJCSDXXLHJHFSSXZQHFZMZCZTQCXZXRTTDJHNNYZQQMNQDMMGYYDXMJGDHCDYZBFFALLZTDLTFXMXQZDNGWQDBDCZJDXBZGSQQDDJCMBKZFFXMKDMDSYYSZCMLJDSYNSPRSKMKMPCKLGDBQTFZSWTFGGLYPLLJZHGJJGYPZLTCSMCNBTJBQFKTHBYZGKPBBYMTTSSXTBNPDKLEYCJNYCDYKZDDHQHSDZSCTARLLTKZLGECLLKJLQJAQNBDKKGHPJTZQKSECSHALQFMMGJNLYJBBTMLYZXDCJPLDLPCQDHZYCBZSCZBZMSLJFLKRZJSNFRGJHXPDHYJYBZGDLQCSEZGXLBLGYXTWMABCHECMWYJYZLLJJYHLGBDJLSLYGKDZPZXJYYZLWCXSZFGWYYDLYHCLJSCMBJHBLYZLYCBLYDPDQYSXQZB" +
                                         "YTDKYXJYYCNRJMDJGKLCLJBCTBJDDBBLBLCZQRPXJCGLZCSHLTOLJNMDDDLNGKAQHQHJGYKHEZNMSHRPHQQJCHGMFPRXHJGDYCHGHLYRZQLCYQJNZSQTKQJYMSZSWLCFQQQXYFGGYPTQWLMCRNFKKFSYYLQBMQAMMMYXCTPSHCPTXXZZSM" + "ALBXYFBPNLSFHTGJWEJJXXGLLJSTGSHJQLZFKCGNNDSZFDEQFHBSAQTGLLBXMMYGSZLDYDQMJJRGBJTKGDHGKBLQKBDMBYLXWCXYTTYBKMRTJZXQJBHLMHMJJZMQASLDCYXYQDLQCAFYWYXQHZ";
            const string lsSecondCh = "亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟" +
                                        "鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠氽籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼" +
                                        "陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻" +
                                        "莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩" +
                                        "咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾" +
                                        "舛夥飧夤夂饣饧饨饩饪饫饬饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕氵汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂" +
                                        "溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃" + "缇缈缋缌缏缑缒缗缙缜缛缟缡缢缣缤缥缦缧缪缫缬缭缯缰缱缲缳缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶" +
                                        "轸轷轹轺轼轾辁辂辄辇辋辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱" +
                                        "煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉礻祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶钷钸钹钺钼钽钿铄铈铉铊铋铌铍铎铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪铩铫铮铯铳铴铵铷铹铼" +
                                        "铽铿锃锂锆锇锉锊锍锎锏锒锓锔锕锖锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤镥镦镧镨镩镪镫镬镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨鸩鸪鸫鸬鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦鹧鹨鹩鹪鹫鹬鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦疋胥皲皴矜耒" +
                                        "耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟" +
                                        "羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅龆龇龈龉龊龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞鲟鲠鲡鲢鲣鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲴鲵鲶鲷鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔" + "鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄";
            var returnPY = "";
            for (var i = 0; i < hz.Length; i++)
            {
                var array = Encoding.Default.GetBytes(hz[i].ToString(CultureInfo.InvariantCulture));
                if (array[0] < 176)  //.非汉字
                {
                    returnPY += hz[i];
                }
                else if (array[0] >= 176 && array[0] <= 215)  //一级汉字
                {
                    if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "匝") >= 0)
                        returnPY += "z";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "压") >= 0)
                        returnPY += "y";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "昔") >= 0)
                        returnPY += "x";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "挖") >= 0)
                        returnPY += "w";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "塌") >= 0)
                        returnPY += "t";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "撒") >= 0)
                        returnPY += "s";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "然") >= 0)
                        returnPY += "r";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "期") >= 0)
                        returnPY += "q";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "啪") >= 0)
                        returnPY += "p";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "哦") >= 0)
                        returnPY += "o";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "拿") >= 0)
                        returnPY += "n";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "妈") >= 0)
                        returnPY += "m";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "垃") >= 0)
                        returnPY += "l";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "喀") >= 0)
                        returnPY += "k";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "击") >= 0)
                        returnPY += "j";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "哈") >= 0)
                        returnPY += "h";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "噶") >= 0)
                        returnPY += "g";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "发") >= 0)
                        returnPY += "f";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "蛾") >= 0)
                        returnPY += "e";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "搭") >= 0)
                        returnPY += "d";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "擦") >= 0)
                        returnPY += "c";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "芭") >= 0)
                        returnPY += "b";
                    else if (String.CompareOrdinal(hz[i].ToString(CultureInfo.InvariantCulture), "啊") >= 0)
                        returnPY += "a";
                }
                else if (array[0] >= 215)    //二级汉字
                {
                    returnPY += lsSecondEng.Substring(lsSecondCh.IndexOf(hz[i].ToString(CultureInfo.InvariantCulture), 0, StringComparison.Ordinal), 1);
                }
            }
            return returnPY.ToLower();
        }

        /// <summary>把汉字转换成拼音(全拼)
        /// 把汉字转换成拼音(全拼)
        /// </summary>
        /// <param name="hzString">汉字字符串</param>
        /// <returns>转换后的拼音(全拼)字符串</returns>
        public static string GetAllPYLetters(this string hzString)
        {
            // 匹配中文字符
            var regex = new Regex("^[/u4e00-/u9fa5]$");
            var pyString = "";
            var noWChar = hzString.ToCharArray();
            for (var j = 0; j < noWChar.Length; j++)
            {
                // 中文字符
                if (regex.IsMatch(noWChar[j].ToString(CultureInfo.InvariantCulture)))
                {
                    var array = Encoding.Default.GetBytes(noWChar[j].ToString(CultureInfo.InvariantCulture));
                    int i1 = array[0];
                    int i2 = array[1];
                    var chrAsc = i1 * 256 + i2 - 65536;
                    if (chrAsc > 0 && chrAsc < 160)
                    {
                        pyString += noWChar[j];
                    }
                    else
                    {
                        // 修正部分文字
                        if (chrAsc == -9254)  // 修正“圳”字
                            pyString += "Zhen";
                        else
                        {
                            for (var i = (PyValue.Length - 1); i >= 0; i--)
                            {
                                if (PyValue[i] > chrAsc) continue;
                                pyString += PyName[i];
                                break;
                            }
                        }
                    }
                }
                // 非中文字符
                else
                {
                    pyString += noWChar[j].ToString(CultureInfo.InvariantCulture);
                }
            }
            return pyString;
        }
        #endregion

        /// <summary>
        /// 获取Ip
        /// </summary>
        public static string GetIp
        {
            get
            {
                var result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (string.IsNullOrEmpty(result))
                {
                    result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                if (string.IsNullOrEmpty(result))
                {
                    result = HttpContext.Current.Request.UserHostAddress;
                }
                return result;
            }
        }

        /// <summary>获取上周开始时间
        /// 获取上周开始时间
        /// </summary>
        public static DateTime GetLastWeekFrom
        {
            get { return DateTime.Now.Date.AddDays(-(int)(DateTime.Now.DayOfWeek) + 1 - 7); }
        }

        /// <summary>获取上周结束时间
        /// 获取上周结束时间
        /// </summary>
        public static DateTime GetLastWeekEnd
        {
            get { return DateTime.Now.Date.AddDays(7 - (int)(DateTime.Now.DayOfWeek) - 7); }
        }

        public static void ResponseEnd<T1, T2>(this HttpContext context, T1 result, T2 msg)
        {
            context.Response.Write(ResultMessage<T1, T2>.ResultMessageJson(result, msg));
            context.Response.End();
        }

        /// <summary>
        /// 获取随机实体
        /// </summary>
        /// <returns></returns>
        public static List<T> GetListGetRandom<T>(this List<T> sources, int count) where T : class
        {
            if (sources == null) return new List<T>();
            if (sources.Count <= count) return sources;

            if (count >= sources.Count) count = sources.Count;
            var rData = new List<T>();
            while (rData.Count < count)
            {
                var tick = DateTime.Now.Ticks;
                var random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
                var ran = random.Next(0, sources.Count);
                if (ran >= sources.Count) ran--;
                if (ran < 0) continue;
                var id = sources[ran];
                if (!rData.Contains(id)) rData.Add(id);
            }
            return rData;
        }

        /// <summary>
        /// XML反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        public static T XmlToList<T>(string path)
        {
            if (File.Exists(path))
            {
                using (var rdr = new StringReader(File.ReadAllText(path)))
                {
                    var serializer = new XmlSerializer(typeof(T));
                    return (T)serializer.Deserialize(rdr);
                }
            }
            return default(T);
        }

        /// <summary>
        /// XML序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static XmlDocument ListToXml<T>(this T sources)
        {
            var xmlDoc = new XmlDocument();
            using (var stringWriter = new StringWriter())
            {
                using (var xmlWriter = new XmlTextWriter(stringWriter))
                {
                    var ns = new XmlSerializerNamespaces();
                    ns.Add(String.Empty, String.Empty);
                    var serializer = new XmlSerializer(typeof(T));
                    serializer.Serialize(xmlWriter, sources, ns);
                    xmlDoc.LoadXml(stringWriter.ToString().Replace("utf-16", "utf-8"));
                }
            }
            return xmlDoc;
        }

        public static void ResponseXml<T>(this T sources)
        {
            ResponseXml(sources.ListToXml().InnerXml);
        }

        public static void ResponseRss<TChannel, TItem>(this TChannel channel, List<TItem> items, string replaceStr)
        {
            const string rss = @"<?xml version=""1.0"" encoding=""utf-8""?>
<rss version=""2.0"">
${content}
</rss>";

            var rStr = channel.ListToXml().InnerXml.ToLower().Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>".ToLower(), "");
            var rItem = items.Aggregate(String.Empty, (current, item) => current + item.ListToXml().InnerXml.ToLower().Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>".ToLower(), ""));
            rStr = rStr.Replace(replaceStr.ToLower(), rItem);
            ResponseXml(rss.Replace("${content}", rStr));
        }

        public static void ResponseRss<TChannel, TItem>(this TChannel channel, List<TItem> item)
        {
            ResponseRss(channel, item, "<ForItem>Item</ForItem>");
        }

        public static void ResponseXml(string xml)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = "Text/XML";
            HttpContext.Current.Response.Expires = 0;
            HttpContext.Current.Response.Cache.SetNoStore();
            HttpContext.Current.Response.Write(xml);
            HttpContext.Current.Response.End();
        }
    }

    public class CommonList<T1>
    {
        public T1 Tt1 { get; set; }
    }
    public class CommonList<T1, T2>
    {
        public T1 Tt1 { get; set; }
        public T2 Tt2 { get; set; }
    }
    public class CommonList<T1, T2, T3>
    {
        public T1 Tt1 { get; set; }
        public T2 Tt2 { get; set; }
        public T3 Tt3 { get; set; }
    }
    public class CommonList<T1, T2, T3, T4>
    {
        public T1 Tt1 { get; set; }
        public T2 Tt2 { get; set; }
        public T3 Tt3 { get; set; }
        public T4 Tt4 { get; set; }
    }

    /// <summary>给js提供返回数据实体
    /// 给js提供返回数据实体
    /// </summary>
    public class ResultMessage
    {
        /// <summary>
        /// 获取返回数据的Json
        /// </summary>
        /// <param name="result"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string ResultMessageJson(int result, string msg)
        {
            return new ResultMessage
            {
                Msg = msg,
                Result = result,
            }.ObjToJson();
        }

        public int Result { get; set; }
        public string Msg { get; set; }
    }

    /// <summary>给js提供返回数据实体
    /// 给js提供返回数据实体
    /// </summary>
    public class ResultMessage<T1, T2>
    {
        /// <summary>
        /// 获取返回数据的Json
        /// </summary>
        /// <param name="result"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string ResultMessageJson(T1 result, T2 msg)
        {
            return new ResultMessage<T1, T2>
            {
                Msg = msg,
                Result = result,
            }.ObjToJson();
        }

        public T1 Result { get; set; }
        public T2 Msg { get; set; }
    }

    /// <summary>
    /// 枚举排序
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class EnumOrder : Attribute
    {
        public int Order { get; set; }

        public bool IsHide { get; set; }
    }

    /// <summary>
    /// 自定义说明
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class CustomDescription : Attribute
    {
        public CustomDescription(string description)
        {
            Description = description;
        }
        public string Description { get; set; }
    }

    /// <summary>
    /// 表单或Url提交过去的参数名，用于自动生成带值的实体
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class SubmitTitle : Attribute
    {
        /// <summary>
        /// 页面显示的字段名称
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 所在的组
        /// </summary>
        public string Group { get; set; }
    }

    /// <summary>
    /// 标记数据库插入更新语句
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class Insert : Attribute
    {
        /// <summary>
        /// 数据库字段
        /// </summary>
        public string Field { get; set; }

        /// <summary>
        /// 所在的组
        /// </summary>
        public string Group { get; set; }

        /// <summary>
        /// 是否用于生成更新语句，只取决定义在类上面的值
        /// </summary>
        public bool IsUpdate { get; set; }
    }
}
